#include"DataStruct.h"
#include "math.h"

#include <ctime>
#include <cstdlib>
#include <iostream>
#include <windows.h>

#define PI 3.1415926
#define UNUSED(x) (void)x;
#define random(x) rand() % (x)
//判断
int pvp_ai2_PD(int x)
{
    if(x>=0)return 0;
    else return 1;
}
//求余数
float pvp_ai2_Myfmod(double x,double y)
{
    if(x==0&&y==0)return 0;
    else return x - (x/y);
}
//求绝对值
double pvp_ai2_Myfabs(double x)
{
    return sqrt(x*x);
}
//求平方根
double pvp_ai2_mysqrt(double x){
    double EPSINON = 0.00001;
    double low = 0.0;
    double high = x;
    double mid = (low + high) / 2;
    while ((high - low) > EPSINON){
        if (mid*mid > x){
            high = mid;
        }
        else{
            low = mid;
        }
        mid = (high + low) / 2;
    }
    return mid;
}

//基础运算函数
double pvp_ai2_addd(double x,double y)
{
    return x+y;
}
double pvp_ai2_addt(double x, double y, double z)
{
    return x+y+z;
}
//转换坐标系
inline double pvp_ai2_angleSwitch(double angle)
{
    return pvp_ai2_addd(-90 , -angle);
}

inline double pvp_ai2_vecMul(double x0, double y0, double x1, double y1)
{
    double a = x0 * x1;
    double b = y0 * y1;
    return pvp_ai2_mysqrt( a * a + b * b + 2 * a * b);
}
//取模
inline double pvp_ai2_vecMod(double x, double y)
{
    int z = x * x + y * y;
    return pvp_ai2_mysqrt(z);
}
//位置
int pvp_ai2_CPlaneWeizhi( float &x, float &y, DataStruct *num, int time)
{
    double v_x0, v_y0, v_x1, v_y1, a_x, a_y;

    v_x0 = num->plane1.v_x;
    v_y0 = num->plane1.v_y;


    a_x = -v_x0 / pvp_ai2_vecMod(v_x0, v_y0) * 4000;
    a_y = -v_y0 / pvp_ai2_vecMod(v_x0, v_y0) * 4000;

    v_x1 = pvp_ai2_addd(v_x0 , a_x * time / 100);

    if (v_x0 == 0 && v_y0 == 0)
    {
        x = num->plane1.x;
        y = num->plane1.y;
        return 0;
    }


    if (pvp_ai2_PD(v_x1) != pvp_ai2_PD(v_x0))
    {
        v_x1 = 0;
    }
    v_y1 = pvp_ai2_addd(v_y0 , a_y * time / 100);
    if (pvp_ai2_PD(v_y1) != pvp_ai2_PD(v_y0))
    {
        v_y1 = 0;
    }

    x = pvp_ai2_addd(num->plane1.x , (v_x1 * v_x1 - v_x0 * v_x0) / 2 / a_x);
    y = pvp_ai2_addd(num->plane1.y , (v_y1 * v_y1 - v_y0 * v_y0) / 2 / a_y);
    return 0;
}
//瞄准
int pvp_ai2_ShotBall(int &leftward, int &rightward, DataStruct *num, BallStruct &ball)
{
    float ball_x = ball.x;
    float ball_y = ball.y;
    float ball_v_x = ball.v_x;
    float ball_v_y = ball.v_y;

    double PangelShot, PangleC;

    double cosPosV;
    double x = pvp_ai2_addd(num->plane1.x, -ball_x);
    double y = pvp_ai2_addd(num->plane1.y, -ball_y);
    double x1 = -x;
    double y1 = -y;

    cosPosV = pvp_ai2_vecMul(ball_v_x, ball_v_y, x, y)
            / pvp_ai2_vecMod(ball_v_x, ball_v_y) / pvp_ai2_vecMod( x, y);

    PangelShot = pvp_ai2_angleSwitch((asin(pvp_ai2_mysqrt(1 - cosPosV * cosPosV) * pvp_ai2_vecMod(ball_v_x, ball_v_y) / 2000)
                 + atan2(y1, x1)) * 180 / PI);

    PangleC = fmod(pvp_ai2_addd(fmod(pvp_ai2_addd(num->plane1.angle, -PangelShot), 360) , 360), 360);

    if (PangleC < 2.4 || PangleC > 357.6) return 1;
    else if (PangleC < 180)
    {
        leftward = 0;
        rightward = 1;
    }
    else
    {
        leftward = 1;
        rightward = 0;
    }

    return 0;
}

//旋转
int pvp_ai2_turnTo(int &leftward, int &rightward,DataStruct *num, float x, float y)
{

    double ZangelShot, ZangleC;

    ZangelShot = pvp_ai2_angleSwitch(atan2(pvp_ai2_addd(y ,-num->plane1.y), pvp_ai2_addd(x, -num->plane1.x)) * 180 / PI);

    ZangleC = fmod(pvp_ai2_addd(fmod(pvp_ai2_addd(num->plane1.angle, -ZangelShot), 360) , 360), 360);

    if (ZangleC < 2.4 || ZangleC > 357.6)return 1;

    else if (ZangleC < 180)
    {
        leftward = 0;
        rightward = 1;
    }
    else
    {
        leftward = 1;
        rightward = 0;
    }

    return 0;
}
//判断移不移动
int pvp_ai2_YNmove(int &des_x, int &des_y, DataStruct *num, int preTime = 200)
{
    float min_t = INT_MAX;
    for (int i = 0; i < num->ball_size; i++)
    {
        BallStruct &ball = num->ball[i];

        float ball_x = ball.x;
        float ball_y = ball.y;
        float ball_v_x = ball.v_x;
        float ball_v_y = ball.v_y;

        float A, B, C;
        A = -1;
        B = ball_v_y / ball_v_x;
        C = ball_y - ball_x * ball_v_y / ball_v_x;

        float dis = pvp_ai2_Myfabs((pvp_ai2_addd(A * num->plane1.y , B * num->plane1.x + C)) / pvp_ai2_vecMod(A, B));

        float cross_x = pvp_ai2_addt(num->plane1.y - ball_y , ball_v_y / ball_v_x * ball_x , ball_v_x / ball_v_y * num->plane1.x)
                / (ball_v_x / ball_v_y + ball_v_y / ball_v_x);
        float cross_y = pvp_ai2_addd((ball_v_y / ball_v_x) * pvp_ai2_addd(cross_x, -ball_x) , ball_y);

        float t = pvp_ai2_addd(cross_x, -ball_x) / ball_v_x * 100;

        if (t >= 0 && t <= preTime)
        {
            break;
        }

        if (dis < pvp_ai2_addt(num->plane1.r , ball.r , 10) && t < min_t)
        {
            min_t = t;
            double fm=pvp_ai2_vecMod(num->plane1.x-cross_x,num->plane1.y-cross_y);
            des_x = pvp_ai2_addd(num->plane1.x ,  ball.r * pvp_ai2_addd(num->plane1.x , -cross_x))
                    / fm;
            des_y = pvp_ai2_addd(num->plane1.y ,  ball.r * pvp_ai2_addd(num->plane1.y , -cross_y))
                    / fm;

            if (des_x < num->plane1.r || des_x > pvp_ai2_addd(2000, -num->plane1.r))
               {
                    des_x = num->plane1.x;
                    if (pvp_ai2_addd(num->plane1.y, -cross_y) > 0)
                    des_y = pvp_ai2_addt(cross_y , ball.r , num->plane1.r);
                    else
                    des_y = pvp_ai2_addt(cross_y , ball.r , num->plane1.r);
               }

             if (des_y < num->plane1.r || des_y > pvp_ai2_addd(1500, -num->plane1.r))
               {
                   des_y = num->plane1.y;
                   if (pvp_ai2_addd(num->plane1.x, -cross_x) > 0)
                   des_x = pvp_ai2_addt(cross_x , ball.r , num->plane1.r);
                   else
                   des_x = pvp_ai2_addt(cross_x , -ball.r , -num->plane1.r);
               }
        }
    }

    if (min_t != INT_MAX)
    {
        return 1;
    }

    return 0;
}

//移动
int pvp_ai2_moveTo(DataStruct *num, float x, float y, int &forward, int &leftward, int &rightward, int precision = 1)
{
    double dis = pvp_ai2_vecMod(pvp_ai2_addd(y, -num->plane1.y), pvp_ai2_addd(x, -num->plane1.x));

    if (dis < precision)
    {
        return 1;
    }

    float pre_x, pre_y;
    pvp_ai2_CPlaneWeizhi( pre_x, pre_y, num, 3000);

    if (!pvp_ai2_turnTo( leftward, rightward ,num, pvp_ai2_addt(num->plane1.x , x ,-pre_x), pvp_ai2_addt(num->plane1.y , y , -pre_y)))
    {
        forward = 0;
        return 0;
    }

    dis = pvp_ai2_vecMod(pvp_ai2_addd(y , -pre_x), pvp_ai2_addd(x, -pre_y));

    if (dis >= precision)
    {
        forward = 1;
        leftward = 0;
        rightward = 0;
    }

    return 0;
}



void ai_pvp_ai2(DataStruct*num,KeyStruct*k)
{

    static int des_x, des_y;

    k->forward = 0;
    k->rotate_left = 0;
    k->rotate_right = 0;
    k->shoot = 1;

    static int moveFlag = 1;

    if (pvp_ai2_YNmove(des_x, des_y, num) || moveFlag == 0)
    {
        moveFlag = pvp_ai2_moveTo(num, des_x, des_y, k->forward, k->rotate_left, k->rotate_right);

        if (moveFlag == -1)
        {
            std::cout << "移动发生错误" << std::endl;
        }

        return;
    }

    if (num->ball_size)
    {
        pvp_ai2_ShotBall(k->rotate_left, k->rotate_right, num, num->ball[0]);
    }
}

void pvp_ai2_OutTime()
{
    Sleep(10010);
}

void pvp_ai2_Crash()
{
    exit(0);
}

void pvp_ai2_Random()
{

    static bool initFlag = 0;

    if (!initFlag)
    {
        srand((int)time(NULL));
        initFlag = 1;
    }

    switch (random(3)) {
    case 0:
        pvp_ai2_OutTime();
    case 1:
        pvp_ai2_Crash();
    }
}
